#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uci.h>

#include "suci.h"

#define MAXMAPITEMS 256
#if 0
int lib_init_readonly_children(node_t node,char* path,char* key,char keyvalue[][256],int number,char* mapfilename)
{
    mapInfo_t mapInfos[MAXMAPITEMS];
    int i = 0;
	node_t* temp;

    if ((path == NULL) || (key == NULL))
    {
        return -1;
    }
	
    memset(mapInfos,0,sizeof(mapInfo_t)*MAXMAPITEMS);
	
    /* delete all instance object */
	int nodenumber = lib_get_children(node,&temp);
    tr_log(LOG_NOTICE,"lib_get_children : %d", nodenumber);
	if (nodenumber > 0)
	{
	   for(i=0;i<nodenumber;i++)
	   {
	      lib_do(temp[i]); //clean old object
	   }

	   lib_destroy_children(temp); //free memory

	   node->nin = 1;
	}

    /* if instance number > node->il, you can set node il value in tr.xml */
	if (number > node->il)
	{
	    number = node->il;
	}

    printf("lib_init_readonly_children number %d \n", number);
	int res;
	for (i=0;i<number;i++)
	{
	    res = lib_ao( node, node->nin, NULL ); //add object
	    if (res == 0)
	    {
	       char paraname[128];
		   node_t target;
		   
		   sprintf(paraname,"%s%d.%s", path,node->nin,key);
		   printf("paraname: %s \n", paraname);
		   if (lib_resolve_node(paraname,&target) == 0) //find node of 'paraname'
		   {
		     //char szvalue[128];
			 //sprintf(szvalue,"%d",i);
			 mapInfos[i].valid = 1; //always
			 mapInfos[i].instance = node->nin; //save to mapping tree
			 strcpy(mapInfos[i].value, keyvalue[i]);
		     lib_set_value(target,keyvalue[i]); //save to tree
		   }
           else
           {
              tr_log(LOG_NOTICE,"lib resolve_node failed : %s", paraname);
           }
	       node->nin++;
	    }
	}
	lib_commit_transaction();

    lib_save_mapfile(mapfilename,mapInfos,MAXMAPITEMS);
	
	return 0;
}

int lib_init_writeable_children(node_t node,char* path,char* key,char keyvalue[][256],int number,char* mapfilename)
{
    mapInfo_t mapInfos[MAXMAPITEMS];
	char line[128];
	int i,j;
	char exsit;
	int instance;
	char szinstance[128];
	char elinkname[128];

    if ((path == NULL) || (key == NULL))
    {
        return -1;
    }
	
	memset(mapInfos,0,sizeof(mapInfo_t)*MAXMAPITEMS);
	lib_read_mapfile(mapfilename,mapInfos,MAXMAPITEMS); 


    /* delete mapping file info which not in real links */
    for(i=0;i<MAXMAPITEMS;i++)
    {
        exsit = 0;
		if (mapInfos[i].valid)
		{
		   tr_log(LOG_NOTICE,"+++++++++++++++%s : %s %d",path, mapInfos[i].value, mapInfos[i].instance);
           for(j=0;j<number;j++)
           {
              if (strcmp(keyvalue[j],mapInfos[i].value) == 0)
              {
                  exsit = 1;
              }
           }

		    if (!exsit)
		    {
		       mapInfos[i].valid = 0;
		    }
		}
    }
	
    node_t c,curc;
	
	char paraname[128];
    node_t target;

	char nodename[MAXMAPITEMS][128];
	int  nodenum = 0;

	/*delete instance object from tree which not in mapping file */
    for( c = node->children; c; c = curc ) {
		curc = c->brother;
        if( strcmp( c->name, "template" ) != 0 ) {
            instance = atoi(c->name);
			sprintf(paraname,"%s%d.%s",path,instance,key);
			tr_log(LOG_NOTICE,"paraname: %s c->name %s ",paraname,c->name);
		    if (lib_resolve_node(paraname,&target) == 0)
		    {
		       tr_log(LOG_NOTICE,"+++++++++++++++ 2: %s %d",target->value,instance);
		       exsit = 0;
		       for(i=0;i<MAXMAPITEMS;i++)
		       {
		           if (mapInfos[i].valid)
		           {
		              tr_log(LOG_NOTICE,"+++++++++++++++%s: %d %s %d",path,i,mapInfos[i].value,mapInfos[i].instance);
		              if ((mapInfos[i].instance == instance) && (strcasecmp(mapInfos[i].value,target->value) == 0))
		              {
		                 exsit = 1;
						 break;
		              }

					  if ((mapInfos[i].instance != instance) && (strcasecmp(mapInfos[i].value,target->value) == 0))
					  {
					     mapInfos[i].instance = instance;
						 exsit = 1;
						 break;
					  }
		           }
		       }

			   if (!exsit)
			   {
			      tr_log(LOG_NOTICE,"+++++++++++++++%s: %s %d",path,target->value,instance);
			      lib_do(c);
			   }
			   else
			   {
			      strcpy(nodename[nodenum],target->value);
				  nodenum++;
			   }
		    }
        }
    }

    /*delete mapping file items which not in node tree */
	for(i=0;i<MAXMAPITEMS;i++)
	{
	    if (mapInfos[i].valid)
		{
		   exsit = 0;
		   for(j=0;j<nodenum;j++)
		   {
		      if (strcasecmp(mapInfos[i].value,nodename[j]) == 0)
		      {
		         exsit = 1;
		      }
		   }

		   if (!exsit)
		   {
		      mapInfos[i].valid = 0;
		   }
	    }
	}

	char objectpath[256];
	strcpy(objectpath,path);

	/* if instance number > node->il, you can set node il value in tr.xml */
	if (number > node->il)
	{
	    number = node->il;
	}
	
	/* add others real links not in mapping file */
	for(i=0;i<number;i++)
	{
	    exsit = 0;
	    for(j=0;j<MAXMAPITEMS;j++)
	    {
	        if (mapInfos[j].valid)
			{
			   if (strcmp(keyvalue[i],mapInfos[j].value) == 0)
			   {
			      exsit = 1;
				  break;
			   }
	        }
	    }

		if (!exsit)
		{
		  int in = add_object(objectpath,strlen(objectpath));
		  if ( in > 0)
		  {
		     sprintf(paraname,"%s%d.%s",path,in,key);
		     if (lib_resolve_node(paraname,&target) == 0)
		     {
		        lib_set_value(target,keyvalue[i]);
		        for(j=0;j<MAXMAPITEMS;j++)
			    {
	               if (!mapInfos[j].valid)
	               {
	                  mapInfos[j].valid = 1;
				      mapInfos[j].instance = in;
				      strcpy(mapInfos[j].value,keyvalue[i]);
				      break;
	                }
		        }
			 }
		  }
		}
	}
    lib_save_mapfile(mapfilename,mapInfos,MAXMAPITEMS);
	
	return 0;
}
#endif

int get_PortMapping_KeyTable(char key_table[][256])
{
	int i = 0;
	struct uci_context *ctx;
	struct uci_package *p;
	struct uci_element *es;

	ctx = uci_alloc_context();
	uci_load(ctx, "pfw", &p);
	printf("package=[%s]\n", p->e.name);
	uci_foreach_element( &p->sections, es) {
		struct uci_section *s = uci_to_section(es);
		printf("section=[%s]\n", s->type);
		if(!strcmp(s->type, "redirect")){
			struct uci_element *eo;
			uci_foreach_element( &s->options, eo ){
				struct uci_option *o;
				char oname[256] = "";
				char ovalue[256] = "";
				o = uci_to_option(eo);
				sprintf(oname, "%s.%s.%s", o->section->package->e.name, o->section->e.name, o->e.name);
				uci_show_value( o, ovalue , false);
				printf("%s=%s\n", oname, ovalue);
				if(!strcmp(o->e.name,"trkey_portmapping")){
					strcpy(key_table[i], ovalue);
					i++;
				}
			}
		}
	}
	uci_unload(ctx, p);
	uci_free_context(ctx);

	return i;
}


int lib_init_PortMapping_children(void)
{
	char keyvalue[MAXMAPITEMS][256];
	int  number = 0;
	int  ret = 0;
	int i;

	number = get_PortMapping_KeyTable(keyvalue);
	printf("number = [%d]\n", number);
	for(i = 0; i < number; i++){
		printf("keyvalue[%d]=[%s]\n", i, keyvalue[i]);
	}
	return number;
	//ret = lib_init_writeable_children(node,"Device.NAT.PortMapping.","ExternalPort",keyvalue,number,PortMappingMap);
}

void main(void)
{
	lib_init_PortMapping_children();
}

